Skip to content

fix(plugin): derive missing crystallization summaries - #2222

Closed
RerankerGuo wants to merge 3 commits into
MemTensor:mainfrom
RerankerGuo:fix/issue-2143-crystallize-summary-fallback
Closed

fix(plugin): derive missing crystallization summaries#2222
RerankerGuo wants to merge 3 commits into
MemTensor:mainfrom
RerankerGuo:fix/issue-2143-crystallize-summary-fallback

Conversation

@RerankerGuo

Copy link
Copy Markdown
Contributor

Description

Fixes #2143.

When the crystallization LLM returns a structurally useful draft but omits
summary, normalization currently produces an empty string and the default
validator rejects the entire draft.

This change derives a sanitized fallback summary in this order:

  1. retrieval_blurb / retrievalBlurb, when provided by older or alternate models
  2. The first normalized step body or title
  3. The normalized display title or skill name
  4. A final static fallback

Existing non-empty summaries are unchanged. Missing steps remain invalid, so
this does not weaken the structural validator.

Related Issue (Required): Fixes #2143

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

  • Unit Test
  • Test Script Or Test Steps

Evidence:

  • Before the fix, the two new regressions failed with
    skill.crystallize.invalid: missing summary.
  • npm test -- tests/unit/skill/crystallize.test.ts -> 9 passed.
  • npm run lint -> TypeScript project check passed.
  • npm run build -> plugin build passed.
  • The broader tests/unit/skill run passed 35 tests; 13 database-backed tests
    could not start because the local Node 26 install lacks the
    better-sqlite3 native binding after an --ignore-scripts install.

Impact

  • Breaking change: no
  • Scope: skill draft normalization only
  • Dependencies: none
  • Existing valid summaries and validation of missing steps are unchanged

Checklist

  • I have performed a self-review of my own code
  • I have added tests that prove the fix is effective
  • I have linked the issue to this PR
  • No documentation update is required for this internal recovery path
  • Review requested from @hijzy and @whipser030

Reviewer Checklist

@Memtensor-AI Memtensor-AI added area:plugin OpenClaw & Hermes status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 5, 2026
@Memtensor-AI

Memtensor-AI commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

🤖 Open Code Review

Target: PR #2222
Task: f0d912ead9bac289
Base: main
Head: fix/issue-2143-crystallize-summary-fallback

🔍 OpenCodeReview found 1 issue(s) in this PR.


1. apps/memos-local-plugin/core/skill/crystallize.ts (L369)

String.prototype.slice counts UTF-16 code units, not Unicode code points or grapheme clusters. For content containing multi-byte characters (e.g., Chinese, Japanese, Korean, emoji), this can silently split a surrogate pair and produce a malformed string. Consider using a Unicode-aware truncation, such as [...summarySource].slice(0, MAX_SUMMARY_LENGTH).join('') (splits by code point), or at minimum document that the limit is in code units.

💡 Suggested Change

Before:

  const summary = summarySource.slice(0, MAX_SUMMARY_LENGTH);

After:

  const summary = [...summarySource].slice(0, MAX_SUMMARY_LENGTH).join("");

Generated by cloud-assistant via Open Code Review.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

✅ Automated Test Results: PASSED

All tests passed (9/9 executed). memos_local_plugin/unit: 9/9. Duration: 3s [advisory, non-gating] AI-generated tests on branch test/auto-gen-32083f8dbbd21f66-20260805162117: 19/19 passed — these do NOT affect the PR verdict; review the branch manually.

Branch: fix/issue-2143-crystallize-summary-fallback

@Memtensor-AI Memtensor-AI added status:ready Ready for implementation; waiting for assignee or AI dispatch | 可进入实现,等待认领或派发 and removed status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 5, 2026
@Memtensor-AI Memtensor-AI added status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 and removed status:ready Ready for implementation; waiting for assignee or AI dispatch | 可进入实现,等待认领或派发 labels Aug 6, 2026
@syzsunshine219

Copy link
Copy Markdown
Collaborator

Updated this PR at a1dcfb2c to address both unresolved OCR findings.

Changes:

  • select the first sanitized summary source, then apply the 200-character cap uniformly to explicit and derived summaries
  • remove the unreachable optional/static fallback; displayTitle is already guaranteed non-empty
  • add a regression test for an explicit 250-character summary (observed failing before the fix, passing after)

Merge status:

  • the PR is already based on the latest main (0 behind / 1 ahead)
  • merge-tree completed without conflicts

Local verification:

  • focused crystallization suite: 10/10 passed
  • complete local-plugin suite: 159 files, 1305 passed, 2 skipped
  • npm run lint: passed
  • npm run build: passed
  • git diff --check: passed

Fresh OCR and AutoTest checks are pending. Python Actions run: https://github.com/MemTensor/MemOS/actions/runs/31122705498 (16 jobs queued while GitHub Actions is under a major outage).

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

✅ Automated Test Results: PASSED

All tests passed (10/10 executed). memos_local_plugin/unit: 10/10. Duration: 3s [advisory, non-gating] AI-generated tests on branch test/auto-gen-afc7396792f82328-20260807012102: 24/25 passed, 1 failed — these do NOT affect the PR verdict; review the branch manually.

Branch: fix/issue-2143-crystallize-summary-fallback

Extract the shared summary clamp into MAX_SUMMARY_LENGTH and cover long retrieval-blurb fallbacks so explicit and derived summaries stay bounded consistently.

Test: npm --prefix apps/memos-local-plugin test -- tests/unit/skill/crystallize.test.ts\nTest: npm --prefix apps/memos-local-plugin run lint\nTest: npm --prefix apps/memos-local-plugin run build
@RerankerGuo

RerankerGuo commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @syzsunshine219 for updating the branch in a1dcfb2c and validating the full plugin suite.

I kept that normalization fix and addressed the remaining OCR finding in 6e824e1c:

  • extracted the shared 200-character cap to MAX_SUMMARY_LENGTH;
  • retained the existing source priority and uniform clamp for explicit and derived summaries;
  • added a regression proving a 250-character retrieval_blurb fallback is sanitized and clamped to 200 characters.

Verification:

  • npm --prefix apps/memos-local-plugin test -- tests/unit/skill/crystallize.test.ts -> 11 passed
  • npm --prefix apps/memos-local-plugin run lint -> passed
  • npm --prefix apps/memos-local-plugin run build -> passed
  • git diff --check -> passed

The complete local-plugin unit run could not complete in this local Node 26 environment because the existing better-sqlite3 native binding is unavailable for Node ABI 147. It reported 955 passed before the database-backed failures. This is the same environment limitation already documented for the earlier branch validation and is unrelated to the two crystallization files.

CI update for run 31557357464:

  • all 8 macOS and all 4 Windows jobs passed;
  • all 4 Ubuntu jobs stopped before build, Ruff, or tests on the unchanged src/memos/embedders/cache.py top-level cachetools import;
  • Open Code Review passed with one non-blocking finding;
  • AutoTest reported an environment issue before tests because its SSH clone failed with kex_exchange_identification: Connection closed by remote host.

I have kept the unrelated core/optional dependency issue out of this PR.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

⚠️ Automated Test Results: ENV ISSUE

The test environment encountered an issue that requires manual attention.

Details: Executor error: Command failed: git clone --depth 1 --branch fix/issue-2143-crystallize-summary-fallback git@github.com:RerankerGuo/MemOS.git /data/test-workspaces/f0d912ead9bac289/repo
Cloning into '/data/test-workspaces/f0d912ead9bac289/repo'...
nc: read failed (0/4): Broken pipe
kex_exchange_identification: Connection closed by remote host
Connection closed by UNKNOWN port 65535
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
Branch: fix/issue-2143-crystallize-summary-fallback

@RerankerGuo RerankerGuo closed this by deleting the head repository Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:plugin OpenClaw & Hermes status:in-progress Someone or AI is working on it | 人工或 AI 正在处理

Projects

None yet

Development

Successfully merging this pull request may close these issues.

crystallize: defaultDraftValidator throws skill.crystallize.invalid: missing summary when LLM omits summary field

4 participants